package com.yupi.springbootinit.manager;

import com.yupi.springbootinit.common.ErrorCode;
import com.yupi.springbootinit.exception.BusinessException;
import org.redisson.api.RRateLimiter;
import org.redisson.api.RateIntervalUnit;
import org.redisson.api.RateType;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

/*
* 专门提供 RedissonLimiter 限流基础服务的 （提供了通用的能力）
* */
@Service
public class RedisLimiterManager {

    @Resource
    private RedissonClient redissonClient;

    /*
    * 限流操纵
    *
    * @param key 区分不同的限流器，比如不同的用户 id 应该分别统计
    * */
    public void doRateLimit(String key) {
        // 创建一个名为 user_limit 的 限流器，每秒最多访问 2 次
        RRateLimiter rateLimiter = redissonClient.getRateLimiter(key);

        //限流器统计规则(每秒2个请求；连续的请求最多只能有一个请求被允许通过)
        // RateType.OVERALL表示速率限制作用于整个令牌桶，
        rateLimiter.trySetRate(RateType.OVERALL, 2, 1, RateIntervalUnit.SECONDS);
        // 每当一个操作来了后，请求一个令牌
        boolean isLimited = rateLimiter.tryAcquire(1);
        // 如果没有令牌，还想执行操作，就抛出异常
        if (!isLimited){
            throw new BusinessException(ErrorCode.TOO_MANY_REQUESTS);
        }
    }
}
